package com.css.fxfzfxqh.modules.lifelineEngineering.service.impl;

import cn.hutool.core.io.FileUtil;
import com.css.fxfzfxqh.base.attachment.entity.AttachmentInfoEntity;
import com.css.fxfzfxqh.base.attachment.service.AttachmentInfoService;
import com.css.fxfzfxqh.base.dict.repository.entity.DictItemEntity;
import com.css.fxfzfxqh.base.response.RestResponse;
import com.css.fxfzfxqh.common.rest.JcsjRestManager;
import com.css.fxfzfxqh.common.rest.model.bo.ysx.AttachmentInfoBo;
import com.css.fxfzfxqh.common.rest.model.bo.ysx.SmxVersionBo;
import com.css.fxfzfxqh.common.rest.model.bo.ysx.SmxVersionInfoBo;
import com.css.fxfzfxqh.common.rest.model.bo.ysx.UploadShpBo;
import com.css.fxfzfxqh.common.rest.model.vo.ysx.AttachmentInfoVo;
import com.css.fxfzfxqh.common.rest.model.vo.ysx.SmxVersionVo;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.BizException;
import com.css.fxfzfxqh.modules.lifelineEngineering.entity.SmxVectorEntity;
import com.css.fxfzfxqh.modules.lifelineEngineering.param.SmxDataParam;
import com.css.fxfzfxqh.modules.lifelineEngineering.param.UploadShpParam;
import com.css.fxfzfxqh.modules.lifelineEngineering.param.VectorDataParam;
import com.css.fxfzfxqh.modules.lifelineEngineering.repository.LifelineVectorRepository;
import com.css.fxfzfxqh.modules.lifelineEngineering.service.LifelineDataMaintenanceService;
import com.css.fxfzfxqh.modules.seismicHazardData.constants.TableNameConstants;
import com.css.fxfzfxqh.modules.util.hypergraph.service.HypergraphService;
import com.css.fxfzfxqh.util.*;
import com.css.fxfzfxqh.zcpt.sys.entity.SUser;
import com.css.fxfzfxqh.zcpt.sys.service.SUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class LifelineDataMaintenanceServiceImpl implements LifelineDataMaintenanceService {

    @Autowired
    private JcsjRestManager jcsjRestManager;

    @Autowired
    private LifelineVectorRepository lifelineVectorRepository;

    @Autowired
    private AttachmentInfoService attachmentInfoService;

    @Autowired
    private SUserService userService;

    @Autowired
    private HypergraphService hypergraphService;


    @Override
    public List<SmxVersionVo> getRepeatData(UploadShpParam param) throws Exception {
        SmxVersionBo repeatData = jcsjRestManager.getRepeatData(param);
        return repeatData.getData();
    }

    @Override
    public Map<String, Object> getVersionCode(UploadShpParam param) throws BizException {
        SmxVersionInfoBo versionCode = jcsjRestManager.getVersionCode(param);
        return versionCode.getData();
    }

    @Override
    public Map<String, Object> getByTypeAndVersionId(SmxDataParam param) throws BizException {
        Map<String, Object> data;
        if(param.getType()>14){
            data = lifelineVectorRepository.getByVersionAndType(param);
        }else {
            SmxVersionInfoBo versionCode = jcsjRestManager.getByTypeAndVersionId(param);
            data = versionCode.getData();
        }
        return data;
    }

    @Override
    public Integer deleteByTypeAndVersionId(String versionId) throws BizException {
        return jcsjRestManager.deleteByTypeAndVersionId(versionId);
    }

    @Override
    public Integer deleteByTypeAndId(Integer type, String ids) throws BizException {
        Integer code = 0;
        if (type > 14) {
            for (String id : ids.split(",")) {
                lifelineVectorRepository.deleteByVersionId(id,type);
            }
            code = RestResponse.succeed().getCode();
        } else {
            code = jcsjRestManager.deleteByTypeAndId(type, ids);
        }
        return code;
    }

    @Override
    public Integer updateById(HashMap<Integer, Object> map) throws BizException {
        return jcsjRestManager.updateById(map);
    }

    @Override
    public UploadShpBo uploadShp(UploadShpParam param) throws Exception {
        return jcsjRestManager.uploadShp(param);
    }

    @Override
    public List<AttachmentInfoVo> uploadFile(List<MultipartFile> file) throws Exception {
        AttachmentInfoBo attachmentInfoBo = jcsjRestManager.uploadFile(file);
        return attachmentInfoBo.getData();
    }

    @Override
    public List<DictItemEntity> getByCode(String code) throws Exception {
        return jcsjRestManager.getByCode(code).getData();
    }

    @Override
    public Integer importHubBuilding(MultipartFile file, Integer type, String province, String city, String county, Integer cover, String id) throws Exception {
        return jcsjRestManager.importHubBuilding(file, type, province, city, county, cover, id);
    }

    @Override
    public int getDataByVersion(String versionId, Integer type) {
        return lifelineVectorRepository.getDataByVersion(versionId, type);
    }

    @Override
    public Map<String, Object> uploadVectorData(VectorDataParam param) throws Exception {
        String table = "fxqh_smx_vector_base_station";
        if(param.getType() == 15){
            table = "fxqh_smx_vector_ts";
        }
        //文件名
        String name = attachmentInfoService.getAttach
                        (param.getFileIds().split(",")[0])
                .getAttachName().split("\\.")[0];
        Map<String, Object> map = new HashMap<>();
        uniformFileName(param.getFileIds());
        ParsingResult shpData = getShpData(param.getFileIds());
        if (param.getCover() == 1) {
            //覆盖，先删除版本下的数据
            lifelineVectorRepository.deleteByVersionId(param.getVersionId(), param.getType());
        }
        //是否成功
        if (!shpData.getMessage().equals("ok")) {
            map.put("res", false);
            map.put("mess", shpData.getMessage());
        }
        List<List<Object>> shpList = shpData.getShpList();

        //上传的ids
        List<String> idsList = shpList.stream()
                .map(shp -> shp.get(1).toString())
                .collect(Collectors.toList());

        //查询变电站或基站此版本下的id
        List<String> data = jcsjRestManager.getVectorDataIdsByVersionId(param.getVersionId(), param.getType()).getData();
        if (PlatformObjectUtils.isEmpty(data)) {
            map.put("res", false);
            map.put("mess","失败,该版本下无基础数据,请先上传!");
        }

        // 相同的id   可以导入的
        List<String> okIds = data.stream()
                .filter(idsList::contains)
                .collect(Collectors.toList());

        //多余的，不可以导入的
        List<String> notIds = idsList.stream()
                .filter(id -> !data.contains(id))
                .collect(Collectors.toList());

        String userId = PlatformSessionUtils.getUserId();
        //用户名字
        String userName = getUserName(userId).getUserName();
        for (int i = 0; i < shpList.size(); i++) {
            List<Object> list = shpList.get(i);
            if (list.size() < 2) {
                return null;
            }
            SmxVectorEntity entity = new SmxVectorEntity();
            entity.setVersionCode(param.getVersionCode());
            entity.setVersionId(param.getVersionId());
            entity.setCreateUser(userId);
            entity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            entity.setDelFlag("0");
            entity.setFileName(name);
            entity.setId(UUIDGenerator.getUUID());
            entity.setCreateUserName(userName);
            if (PlatformObjectUtils.isNotEmpty(list.get(0))) {
                entity.setGeom(list.get(0).toString());
            }
            if (PlatformObjectUtils.isNotEmpty(list.get(1))) {
                entity.setVectorId(ShpAnalyticUtil.getStringVal(list.get(1).toString(), "", false));
            }
            if(okIds.contains(entity.getVectorId())){
                boolean res = lifelineVectorRepository.save(entity, param.getType(),table);
                map.put("res", res);
            }
        }
        StringBuilder str = new StringBuilder("成功导入"+okIds.size()+"条数据");
        if(PlatformObjectUtils.isNotEmpty(notIds)){
            str.append(",有"+notIds.size()+"导入失败,原因:{没有与基础数据id匹配的基础数据!}");
        }
        hypergraphService.getWorkspaceReload(table);
        map.put("mess",str);
        return map;
    }

    /**
     * 获取用户名字
     *
     * @return
     */
    public SUser getUserName(String userId) {
        String user = userService.getSUser(userId);
        return CreateGson.createGson().fromJson(user, SUser.class);
    }

    @Value("${image.localDir}")
    private String localDir;

    /**
     * 统一文件名
     *
     * @param fileIds
     */
    public void uniformFileName(String fileIds) {
        String[] idList = fileIds.split(",");
        AttachmentInfoEntity attachRoot = attachmentInfoService.getAttach(idList[0]);
        String attachRootPath = attachRoot.getAttachPath();
        String filePathCurrTime = getFilePathCurrTime(attachRootPath);
        for (int i = 1; i < idList.length; i++) {
            AttachmentInfoEntity attach = attachmentInfoService.getAttach(idList[i]);
            if (getFilePathCurrTime(attach.getAttachPath()).equals(filePathCurrTime)) {
                continue;
            }
            String attachPath = attach.getAttachPath();
            String fileDiskPath = localDir + attachPath;
            FileUtil.rename(new File(fileDiskPath), getNonSuffixFileName(attach.getAttachName()) + "_" + filePathCurrTime + "." + FileUtil.getSuffix(attach.getAttachName()), true);
            String[] s = attachPath.split("_");
            attach.setAttachPath(s[0] + "_" + filePathCurrTime + "." + FileUtil.getSuffix(attach.getAttachName()));
            attachmentInfoService.update(attach);
        }
    }

    private String getFilePathCurrTime(String filePath) {
        return filePath.split("_")[1].replaceAll("." + FileUtil.getSuffix(filePath.split("_")[1]), "");
    }

    private String getNonSuffixFileName(String fileName) {
        return fileName.replaceAll("." + FileUtil.getSuffix(fileName), "");
    }

    public ParsingResult getShpData(String fileIds) {
        //.prj结尾用来校验是否为2000坐标系
        String prj = "";
        //.cpg文件用来获得编码格式,例如utf-8
        String cpg = "";
        //.shp文件用来获得数据
        String shp = "";
        //根据id获取真实地址
        String[] split = fileIds.split(",");
        for (String id : split) {
            //根据id和文件名获取真实的放在磁盘上的文件
            AttachmentInfoEntity attachmentInfoEntity = attachmentInfoService.getAttach(id);
            String attachPath = attachmentInfoEntity.getAttachPath();
            String substring = attachPath.substring(attachPath.length() - 4);
            if (substring.equals(".prj")) {
                prj = localDir + File.separator + attachPath;
            } else if (substring.equals(".cpg")) {
                cpg = localDir + File.separator + attachPath;
            } else if (substring.equals(".shp")) {
                shp = localDir + File.separator + attachPath;
            }
        }
        return ShpAnalyticUtil.analytic(prj, cpg, shp);
    }
}
